从一个 Activity 启动另一个 Activity 会有哪些生命周期的回调?比如 Activity A 通过 startActivity() 启动 Activity B,默认启动模式下它们的生命周期回调是这样的:
1 | Activity A:onPaused |
所以接下来就开始分析从调用 startActivity() 开始都经过了哪些类哪些方法。本篇不会很详细地分析启动流程的各个方法,只会让你对整个流程有个理性的认识。
温馨提示:强烈推荐跟着文章一边看源码一边画流程,否则后果自负。
1 请求启动
1.1 启动过程
首先看看调用 startActivity() 时都会执行哪些方法:
1 |
|
很明显,当调用 startActivity() 时内部调用的是 startActivityForResult(),并且传递的 requestCode 为 -1。所以如果是通过 startActivityForResult() 启动另一个 Activity 时 requestCode 必须大于等于 0,否则是不会回调 onActivityResult() 的。
在上面最后一个 startActivityForResult() 中只需关注 mParent == null 的情况。
在第 21 行调用了Instrumentation 的 execStartActivity() 方法,这个 Instrumentation 是什么鬼?其实 Instrumentation 是 Android 系统中启动 Activity 的实际操作类。
execStartActivity() 方法有个参数需要注意下:mMainThread.getApplicationThread(),这里是拿到 ActivityThread 类的内部类 ApplicationThread 的对象,并且 ApplicationThread 继承自 ApplicationThreadNative:
1 | public final class ActivityThread { |
往下看 execStartActivity():
1 | public ActivityResult execStartActivity( |
先看看第14行的 checkStartActivityResult() 方法实现:
1 | public static void checkStartActivityResult(int res, Object intent) { |
嗯,就是检查启动 Activity 的结果,最熟悉的应该就是那个“Unable to find explicit activity class XXX; have you declared this activity in your AndroidManifest.xml?”
所以在 checkStartActivityResult() 前面的那句 ActivityManagerNative.getDefault().startActivity()
主要就是用来启动 Activity 的,这个 ActivityManagerNative 又是个什么鬼?先看看 getDefault():
1 | static public IActivityManager getDefault() { |
所以 getDefault() 就是拿到 IActivityManager 的单例对象,即通过 asInterface() 返回的 ActivityManagerProxy 对象。看到这里有发现什么东西么?没有?Binder ?那就再看看 ActivityManagerProxy 的 startActivity():
1 | public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, |
看第 27 行 mRemote.transact() 是不是一切明朗了?还是不懂?那就简单说一下:应用进程与系统进程是两个不同的进程,它们之间需要通过跨进程来通信,类似于客户端与服务端。客户端通过 transact() 方法来发起 RPC(远程过程调用)请求,这个请求被系统底层封装后交给服务端,然后服务端的 onTransact() 方法就会被调用。
ActivityManagerProxy 是 ActivityManagerNative 的内部类,都实现了 IActivityManager 接口,在这里它们都是客户端,服务端就是 ActivityManagerService 即传说中的 AMS。
1.2 小结:
- 通过 startActivity() 或 startActivityForResult() 启动 Activity 最后都是调用了 startActivityForResult(),区别就是 startActivity() 传递的 requestCode = -1;
- 启动 Activity 最终都会交给 Instrumentation 来处理,然后再由 ActivityManagerProxy 通过 Binder 的进程间通信交给 ActivityManagerService 来处理。
2 onPause() 的回调
2.1 AMS 接收启动请求
根据上面的分析,此时应该进入到 ActivityManagerService 的 onTransact() 方法,并且 code 是 START_ACTIVITY_TRANSACTION
:
1 |
|
在第 6 行直接调用了父类的 onTransact() 来处理,它的父类又是谁呢?
1 | public final class ActivityManagerService extends ActivityManagerNative |
有木有感觉被套路了一波?从 ActivityManagerNative 跨进程发送消息到 ActivityManagerService,结果又回到了 ActivityManagerNative。所以还是回到 ActivityManagerNative 的 onTransact,并且 code 是 START_ACTIVITY_TRANSACTION
:
1 |
|
第20行,终于到了 ActivityManagerService 的 startActivity():
1 |
|
ActivityManagerService 的 startActivityAsUser() 方法又调用了 ActivityStarter 的 startActivityMayWait() 方法,所以看看 startActivityMayWait() :
1 | final int startActivityMayWait(IApplicationThread caller, int callingUid, |
上面第 11 行调用了 startActivityLocked() 方法,然后在第36行调用了 startActivityUnchecked(),接着在第57行调用了 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked() 方法。所以接下来看看 resumeFocusedStackTopActivityLocked() 方法:
1 | boolean resumeFocusedStackTopActivityLocked( |
在第 4 行调用了 ActivityStack 的 resumeTopActivityUncheckedLocked():
1 | boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { |
第 22 行那里先进行判断该 Acitvity 是否正处于暂停。第 36 行和 43 行是两个比较重要的方法调用,先来看看 startPausingLocked():
2.2 栈顶 Activity 的 onPause()
1 | final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, |
第 11 行 prev.app.thread.schedulePauseActivity()
,这个 thread 其实是个 IApplicationThread 类型的对象,在 ActivityThread 中有看到内部类 ApplicationThread 以及它的父类 ApplicationThreadNative,而 ApplicationThreadNative 又继承了 Binder 并且实现了 IApplicationThread。不难看出,这里也是进行跨进程通信的,thread 是个客户端,而 ApplicationThread 则是服务端。
接下来继续看 AppicationThread 的 schedulePauseActivity():
1 | public final void schedulePauseActivity(IBinder token, boolean finished, |
很明显,这里通过 H 发送了一个 PAUSE_ACTIVITY_FINISHING
的消息,看看是怎么处理的:
1 | public void handleMessage(Message msg) { |
首先在第 7 行调用了 ActivityThread 的 handlePauseActivity() 方法,后面几个方法都是在 ActivityThread 里面的跳转,最后跳转到了 Instrumentation 的 callActivityOnPause():
1 | public void callActivityOnPause(Activity activity) { |
直接调用了 Activity 的 performPause():
1 | final void performPause() { |
终于在第 5 行看到了第一个生命周期方法 onPause() 的回调,不容易啊。
回到 ActivityStack 的 resumeTopActivityInnerLocked() 方法,有一句 mStackSupervisor.startSpecificActivityLocked(next, true, false)
,所以看看 startSpecificActivityLocked() 方法:
1 | void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { |
首先会判断目标 Activity 所需的应用进程是否已经启动,如果已经启动了就直接调用 realStartActivityLocked() 方法,否则就调用 startProcessLocked() 方法来启动应用进程。
2.3 小结
对比 ApplicationThread 和 ActivityManagerNative:
通过 ActivityManagerNative -> ActivityManagerService 实现了应用进程与 SystemServer 进程的通讯
通过 app.thread -> AppicationThread 实现了 SystemServer 进程与应用进程的通讯
3 启动 Activity 所需的进程
3.1 启动 Activity 所需的进程
接下来看看启动应用进程的过程,首先是 AMS 的 startProcessLocked():
1 | final ProcessRecord startProcessLocked(String processName, |
经过几个重载的 startProcessLocked() 方法后进入了 Process 的 start():
1 | public static final ProcessStartResult start(final String processClass, |
在 zygoteSendArgsAndGetResult() 方法中通过 socket 的方式让 Zygote 进程 fork 了一个新的进程,并且根据“android.app.ActivityThread”字符串反射出该对象并执行 ActivityThread 的 main() 方法。
接下来看看 ActivityThread 的 main() 方法:
1 | public static void main(String[] args) { |
main() 方法主要做了一些初始化的事情,然后调用了 attach() 方法。前面已经分析过了,ActivityManagerNative 是 AMS 的客户端,所以第 49 行的 mgr.attachApplication(mAppThread)
就是通过 Binder 调用了 AMS 的 attachApplication() 方法:
1 |
|
可以看到,在 attachApplication() 方法中调用了 attachApplicationLocked(),在 attachApplicationLocked() 方法中又调用了 ActivityStackSupervisor 的 attachApplicationLocked() 方法(上面第16行处)。
attachApplicationLocked 这个方法比较长(这里省略了大部分),其实它执行了一系列的初始化操作,这样整个应用进程就启动了。
3.2 小结
4 onCreate() 的回调
4.1 接收 SystemService 消息
接着看 ActivityStackSupervisor 的 attachApplicationLocked() 方法:
1 | boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { |
在 attachApplicationLocked() 方法中调用了 realStartActivityLocked() 方法,通过方法名字就知道是用来启动 Activity 的。
realStartActivityLocked() 中和栈顶 Activity 的 onPause() 过程相似,也是通过调用 app.thread 即 IApplicationThread 的方法 scheduleLaunchActivity() 来实现的。所以类似的,最后也会去到 ApplicationThread 的 scheduleLaunchActivity() 方法。
4.2 ActivityThread 处理消息
所以下面看看 ApplicationThread 的 scheduleLaunchActivity() 方法:
1 |
|
还是一样的逻辑,scheduleLaunchActivity() 会通过 ActivityThread 的内部类 H 来分发消息,然后再调用 ActivityThread 的 handleLaunchActivity() 方法:
1 | private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { |
handleLaunchActivity() 方法调用了 performLaunchActivity() 方法,而 performLaunchActivity() 方法又调用了 Instrumentation 的 callActivityOnCreate() 方法:
1 | public void callActivityOnCreate(Activity activity, Bundle icicle, |
在 callActivityOnCreate() 方法里面又调用了 Activity 的 performCreate() 方法:
1 | final void performCreate(Bundle icicle) { |
哈哈,终于见到了 onCreate() 方法。
4.3 小节
这个过程其实主要就是 AMS 通过 Binder 向 ActivityThread 发送启动 Activity 的消息。
5 onStart() 的回调
回到 ActivityThread 的 performLaunchActivity() 方法中,在调用 mInstrumentation.callActivityOnCreate()
之后还调用了 activity.performStart()
,即到了 Activity 的 performStart() 方法:
1 | final void performStart() { |
performStart() 方法中又调用了 Instrumentation.callActivityOnStart()
,所以再看 callActivityOnStart() 方法:
1 | public void callActivityOnStart(Activity activity) { |
直接调用了 Activity 的 onStart() 方法,这是第三个生命周期方法的回调了,绕了一圈,好晕。
6 onResume() 的回调
回到 ActivityThread 的 handleLaunchActivity() 方法,在调用 performLaunchActivity() 方法之后还调用了 handleResumeActivity() 方法,看名字像是回调 onResume() 方法的,那么看看 handleResumeActivity() 方法:
1 | final void handleResumeActivity(IBinder token, |
在第 5 行代码处调用了 performResumeActivity(),来看一下 performResumeActivity() 方法:
1 | public final ActivityClientRecord performResumeActivity(IBinder token, |
在上述的第 8 行代码处又调用了 Activity 的 performResume() 方法,根据前面分析过程,看到这就知道有戏。所以再来看 Activity 的 performResume() 方法:
1 | final void performResume() { |
又跑到了 Instrumentation 去了,看看 callActivityOnResume() 方法:
1 | public void callActivityOnResume(Activity activity) { |
第 3 行处调用了 Activity 的 onResume() 方法,这是第四个生命周期方法的回调了。但是这回就没什么兴奋的了,毕竟都已经猜到了。
7 onStop() 的回调
回到 handleResumeActivity() 方法,在调用 performResumeActivity() 方法之后还调用了 Looper.myQueue().addIdleHandler(new Idler())
,这句代码是异步消息机制相关的代码,来看看 Idler 的实现:
1 | private class Idler implements MessageQueue.IdleHandler { |
在上述第 21 行调用了 activityIdle() 方法,经过前面的分析知道这里又是 Binder 通信,ActivityManagerNative.getDefault() 就是 AMS,所以最后就到了 ActivityManagerService 的 activityIdle() 方法:
1 |
|
在上述第 8 行代码调用了ActivityStackSupervisor 的 activityIdleInternalLocked() 方法:
1 | final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, |
然后在上述第 11 行处调用了ActivityStack 的 stopActivityLocked() 方法:
1 | final void stopActivityLocked(ActivityRecord r) { |
上述代码第 10 行 r.app.thread.scheduleStopActivity()
,好吧,都是同一个套路。通过 IApplicationThread 的 scheduleStopActivity() 方法最终调用了 ActivityThread 的 scheduleStopActivity() 方法:
1 | public final void scheduleStopActivity(IBinder token, boolean showWindow, |
还是一样的配方,还是熟悉的味道。scheduleStopActivity() 方法最终都会调用 ActivityThread 的 sendMessage() 方法,然后在 H 的 handleMessage() 方法中处理。在 handleMessage() 方法中调用了 handleStopActivity() 方法:
1 | private void handleStopActivity(IBinder token, boolean show, int configChanges) { |
handleStopActivity() 方法调用了 performStopActivityInner() 方法,performStopActivityInner() 方法又调用了 Activity 的 performStop() 方法:
1 | final void performStop() { |
上述代码第 8 行调用了 Instrumentation 的 callActivityOnStop() 方法:
1 | public void callActivityOnStop(Activity activity) { |
简单又简洁,直接调用了 Activity 的 onStop() 方法。至此,五个回调方法都搞定了。
附送两张图,这是本人在分析这个过程记录的流程图: